/**
 * gislin 2017年7月21日
 */
package com.btcode.db.executer;

import com.btcode.db.sqlparameter.SQLParameterList;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author gislin 2017年7月21日
 */
public class SQLAndParameter {

    String sql;

    PreparedStatement parameter = null;

    Connection conn;

    List<String> paramKeys = new ArrayList<>();

    public SQLAndParameter(String sql, PreparedStatement parameter) {
        this.sql = sql;
        this.parameter = parameter;
    }

    public SQLAndParameter(String sql, SQLParameterList parameters, Connection conn) {
        this.conn = conn;
        initSQLAndParamKeys(sql, parameters, conn);
        setParameter(parameter);
    }

    private void initSQLAndParamKeys(String sql, SQLParameterList parameters, Connection conn) {
        try {
            String regEx = "@(.+?)[\\s,)$]";
            Pattern p = Pattern.compile(regEx);
            Matcher m = p.matcher(sql + " ");

            String finalSQL = sql;

            while (m.find()) {
                String parameterName = m.group().replaceFirst("@", "").trim().replace(",", "")
                    .replace(")", "");
                paramKeys.add(parameterName);
                finalSQL = finalSQL.replaceFirst("@" + parameterName, "?");
            }

            parameter = conn.prepareStatement(finalSQL);

            this.sql = finalSQL;

        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private void setSQLParameter(SQLParameterList parameters) throws SQLException {

        if (parameter == null) {
            initSQLAndParamKeys(sql, parameters, conn);
        }

        for (int i = 0; i < paramKeys.size(); i++) {
            String parameterName = paramKeys.get(i);
            Object paramValue = parameters.get(parameterName);
            parameter.setObject(i + 1, paramValue);
        }
    }

    public void addBatchParameter(SQLParameterList parameters) throws SQLException {
        setSQLParameter(parameters);
        parameter.addBatch();
    }

    public String getSql() {
        return sql;
    }

    public void setSql(String sql) {
        this.sql = sql;
    }

    public PreparedStatement getParameter() {
        return parameter;
    }

    public void setParameter(PreparedStatement parameter) {
        this.parameter = parameter;
    }

}
